#include "RF24L01.h"

// 寄存器初始化配置
const unsigned char InitRegMap[20][2] = 
{
    //中断线设置 CRC 电源 RX或TX模式
    { CONFIG,       /*MASK_RX_DR | MASK_TX_DS | MASK_MAX_RT | */EN_CRC /*| CRC_2BYTE*/ | CRC_1BYTE },
    
    //自动应答哪些通道
    { EN_AA,        ENAA_P0 | ENAA_P1 | ENAA_P2 | ENAA_P3 | ENAA_P4 | ENAA_P5 },
    
    //接收哪些通道数据
    { EN_RXADDR,    ERX_P0 | ERX_P1 /*| ERX_P2 | ERX_P3 | ERX_P4 | ERX_P5 */},
    
    //地址宽度
    { SETUP_AW,     AW_5BYTES /*AW_3BYTES AW_4BYTES */},
    
    //自动应答延时时长, 次数
    { SETUP_RETR,   AUTO_RETRANSMISSION_DELAY | REPEAT_CNT },
    
    //频点设置
    { RF_CH,        0x02 },
    
    //连续发射 空中波特率 功率
    { RF_SETUP,     RF_DR_LOW_250K /*| PWR_F18DB | RF_DR_HIGH_1M | RF_DR_HIGH_2M */| PWR_0DB /*| PWR_F6DB | PWR_F12DB */},
    
    //各通道数据长度,或最大长度
    { RX_PW_P0,     PIPE0_PACKET_LEN },
    { RX_PW_P1,     PIPE1_PACKET_LEN },
    { RX_PW_P2,     PIPE2_PACKET_LEN },
    { RX_PW_P3,     PIPE3_PACKET_LEN },
    { RX_PW_P4,     PIPE4_PACKET_LEN },
    { RX_PW_P5,     PIPE5_PACKET_LEN },
    
    //各通道动态数据包的开关
    { DYNPD,        /*DPL_P0 | DPL_P1 | DPL_P2 | DPL_P3 | DPL_P4 | DPL_P5 |*/ DPL_NO_PIPE },
    
    //动态数据包 ACK载荷 动态选择NoACK 的开关
    { FEATRUE,      /*EN_DPL | EN_ACK_PAY | EN_DYN_ACK */ FEATURE_ALL_DISABLE },
    { 0xFF, 0xFF}
};

//触发发送,CE保持10us
void NRF24L01_Trig_Tx( void )
{
    RF24L01_SET_CE_HIGH( );
    delay_us( 20 );
    RF24L01_SET_CE_LOW( );

}

//打开电源
void NRF24L01_PowerUp( void )
{
    NRF24L01_Write_Reg( CONFIG , NRF24L01_Read_Reg( CONFIG ) | PWR_UP );
}

//关闭电源,进入待机模式
void NRF24L01_Standby( void )
{
    NRF24L01_Write_Reg( CONFIG , NRF24L01_Read_Reg( CONFIG ) & ( ~PWR_UP ));
}

// 设置模式
void NRF24L01_Set_Mode( nRf24l01ModeType Mode )
{
    uint8_t reg = 0;
    reg = NRF24L01_Read_Reg( CONFIG );
    reg = ( Mode == MODE_RX ) ? ( reg | PRIM_RX ) : ( reg & ( ~PRIM_RX ));
    NRF24L01_Write_Reg( CONFIG, reg );
}

// 设置自动重传的延时和重传次数
void NRF24L01_Set_ReTransmission( unsigned char DelayTimesOf250us, unsigned char RetransmitCount)
{
    RF24L01_SET_CS_LOW( );
    drv_spi_read_write_byte( NRF_WRITE_REG | SETUP_RETR );
    drv_spi_read_write_byte(( DelayTimesOf250us << 4 ) | RetransmitCount );
    RF24L01_SET_CS_HIGH( );
}

 // 设置发送地址
void NRF24L01_Set_TxAddr( uint8_t *pAddr, uint8_t len )
{
    len = ( len > 5 ) ? 5 : len;                  //地址不能大于5个字节
    NRF24L01_Write_Buf( TX_ADDR, pAddr, len );    //写地址
}

//  写接收通道地址
void NRF24L01_Set_RxAddr( uint8_t PipeNum, uint8_t *pAddr, uint8_t Len )
{
    Len = ( Len > 5 ) ? 5 : Len;
    PipeNum = ( PipeNum > 5 ) ? 5 : PipeNum;                    //通道不大于5 地址长度不大于5个字节
    NRF24L01_Write_Buf( RX_ADDR_P0 + PipeNum, pAddr, Len );     //写入地址
}

// 设置速度
void NRF24L01_Set_Speed( uint8_t speed )
{
    uint8_t btmp;
    btmp = NRF24L01_Read_Reg( RF_SETUP );
    btmp &= 0xD7;
    btmp |= speed;
    NRF24L01_Write_Reg( RF_SETUP, btmp );
}

 // 设置功率
void NRF24L01_Set_Power( uint8_t power )
{
    uint8_t btmp;
    btmp = NRF24L01_Read_Reg( RF_SETUP );
    btmp &= 0xF9;
    btmp |= power;
    NRF24L01_Write_Reg( RF_SETUP, btmp );
}

// 设置频率频点
void RF24LL01_Set_FreqPoint( uint8_t FreqPoint )
{
    NRF24L01_Write_Reg(  RF_CH, FreqPoint & 0x7F );
}

// 清TX FIFO
void NRF24L01_Flush_Tx_Fifo ( void )
{
    RF24L01_SET_CS_LOW( );
    drv_spi_read_write_byte( FLUSH_TX );
    RF24L01_SET_CS_HIGH( );
}

// 清RX FIFO
void NRF24L01_Flush_Rx_Fifo( void )
{
    RF24L01_SET_CS_LOW( );        //片选
    drv_spi_read_write_byte( FLUSH_RX );    //清RX FIFO命令
    RF24L01_SET_CS_HIGH( );        //取消片选
}

// 重用上一数据包
void NRF24L01_Reuse_Tx_Payload( void )
{
    RF24L01_SET_CS_LOW( );
    drv_spi_read_write_byte( REUSE_TX_PL );
    RF24L01_SET_CS_HIGH( );
}

// 空操作,可读取STATUS
uint8_t NRF24L01_Nop( void )
{
    uint8_t tmp;
    RF24L01_SET_CS_LOW( );
    tmp = drv_spi_read_write_byte( NOP );
    RF24L01_SET_CS_HIGH( );
    return tmp;
}

// 读状态寄存器
uint8_t NRF24L01_Read_Status_Register( void )
{
    uint8_t Status;
    RF24L01_SET_CS_LOW( );
    Status = drv_spi_read_write_byte( NRF_READ_REG + STATUS );
    RF24L01_SET_CS_HIGH( );
    return Status;
}

// 清中断
uint8_t NRF24L01_Clear_IRQ_Flag( uint8_t IRQ_Source )
{
    uint8_t btmp = 0;
    IRQ_Source &= ( RX_DR | TX_DS | MAX_RT );                           //保证没有传入其它位
    btmp = NRF24L01_Read_Status_Register( );                            //读状态寄存器
    RF24L01_SET_CS_LOW( );                                              //片选
    drv_spi_read_write_byte( NRF_WRITE_REG + STATUS );                  //写状态寄存器命令
    drv_spi_read_write_byte( IRQ_Source | btmp );                       //清相应中断标志
    RF24L01_SET_CS_HIGH( );                                             //取消片选
    return ( NRF24L01_Read_Status_Register( ));                         //返回状态寄存器状态
}

// 读某一个或几个中断状态
uint8_t NRF24L01_Read_IRQ_Status( uint8_t IRQ_Source )
{
    return ( NRF24L01_Read_Status_Register( ) & IRQ_Source );                   //返回中断状态
}

//读取重传次数
uint8_t NRF24L01_Read_ReTransmission_Count( void )
{
    return NRF24L01_Read_Reg( OBSERVE_TX ) & 0x0F;
}

//读取丢包个数
uint8_t NRF24L01_Read_LostPackets_Count( void )
{
    return NRF24L01_Read_Reg( OBSERVE_TX ) >> 4;
}

// 读FIFO中数据宽度
uint8_t NRF24L01_Read_Top_Fifo_Width( void )
{
    uint8_t btmp;
    RF24L01_SET_CS_LOW( );                      //片选
    drv_spi_read_write_byte( R_RX_PL_WID );     //读FIFO中数据宽度命令
    btmp = drv_spi_read_write_byte( 0xFF );     //读数据
    RF24L01_SET_CS_HIGH( );                     //取消片选
    return btmp;
}

// 写带ACK的数据到FIFO
void NRF24L01_Write_Tx_Payload_Ack( uint8_t *pTxBuf, uint8_t len )
{
    uint8_t btmp;
    uint8_t length = ( len > 32 ) ? 32 : len;           //数据长达大约32 则只发送32个
    RF24L01_SET_CS_LOW( );                              //片选
    drv_spi_read_write_byte( WR_TX_PLOAD );             //发送命令
    for( btmp = 0; btmp < length; btmp ++ )
    {
        drv_spi_read_write_byte( *( pTxBuf + btmp ) );  //发送数据
    }
    RF24L01_SET_CS_HIGH( );                             //取消片选
}

// 写不带应答的数据到FIFO
void NRF24L01_Write_Tx_Payload_NoAck( uint8_t *pTxBuf, uint8_t len )
{
    uint8_t length = ( len > 32 ) ? 32 : len;           //数据长达大约32 则只发送32个
    RF24L01_SET_CS_LOW( );                              //片选
    drv_spi_read_write_byte( WR_TX_PLOAD_NACK );        //发送命令
    while( length-- )
    {
        drv_spi_read_write_byte( *pTxBuf );             //发送数据
        pTxBuf++;
    }
    RF24L01_SET_CS_HIGH( );                             //取消片选
}

 // 接收模式下写入附带在ACK中的数据到 ACK FIFO
void NRF24L01_Write_Tx_Payload_InAck( uint8_t *pData, uint8_t len )
{
    uint8_t btmp;
    len = ( len > 32 ) ? 32 : len;                      //数据长度大于32个则只写32个字节
    RF24L01_SET_CS_LOW( );                              //片选
    drv_spi_read_write_byte( W_ACK_PLOAD );             //命令
    for( btmp = 0; btmp < len; btmp ++ )
    {
        drv_spi_read_write_byte( *( pData + btmp ) );   //写数据
    }
    RF24L01_SET_CS_HIGH( );                             //取消片选
}

// 读寄存器
uint8_t NRF24L01_Read_Reg( uint8_t RegAddr )
{
    uint8_t btmp;
    RF24L01_SET_CS_LOW( );
    drv_spi_read_write_byte( NRF_READ_REG | RegAddr );
    btmp = drv_spi_read_write_byte( 0xFF );
    RF24L01_SET_CS_HIGH( );
    return btmp;
}

// 读指定长度的数据

void NRF24L01_Read_Buf( uint8_t RegAddr, uint8_t *pBuf, uint8_t len )
{
    uint8_t btmp;
    
    RF24L01_SET_CS_LOW( );                                  //片选
    drv_spi_read_write_byte( NRF_READ_REG | RegAddr );      //读命令 地址
    for( btmp = 0; btmp < len; btmp ++ )
    {
        *( pBuf + btmp ) = drv_spi_read_write_byte( 0xFF ); //读数据
    }
    RF24L01_SET_CS_HIGH( );                                 //取消片选
}

// 写寄存器
void NRF24L01_Write_Reg( uint8_t RegAddr, uint8_t Value )
{
    RF24L01_SET_CS_LOW( );                                  //片选
    drv_spi_read_write_byte( NRF_WRITE_REG | RegAddr );     //写命令 地址
    drv_spi_read_write_byte( Value );                       //写数据
    RF24L01_SET_CS_HIGH( );                                 //取消片选
}

// 写指定长度的数据
void NRF24L01_Write_Buf( uint8_t RegAddr, uint8_t *pBuf, uint8_t len )
{
    uint8_t i;
    
    RF24L01_SET_CS_LOW( );
    drv_spi_read_write_byte( NRF_WRITE_REG | RegAddr );
    for( i = 0; i < len; i ++ )
    {
        drv_spi_read_write_byte( *( pBuf + i ) );
    }
    RF24L01_SET_CS_HIGH( );
}

void NRF24L01_Init( void )
{
    uint8_t i;
    for( i = 0; i < 20; i++ )
    {
        //写入固定的初始化数据
        if( InitRegMap[i][0] != 0xFF )
        {
          NRF24L01_Write_Reg( InitRegMap[i][0], InitRegMap[i][1] );
        }else{
            break;
        }
    }
}


